﻿using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using System;
using System.IO;

namespace LuceneConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            // Ensures index backward compatibility
            const LuceneVersion AppLuceneVersion = LuceneVersion.LUCENE_48;

            // Construct a machine-independent path for the index
            var basePath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
            basePath = AppDomain.CurrentDomain.BaseDirectory;


            var indexPath = Path.Combine(basePath, "index");
            if (File.Exists(indexPath))
                File.Create(indexPath);


            using var dir = FSDirectory.Open(indexPath);

            // Create an analyzer to process the text
            var analyzer = new StandardAnalyzer(AppLuceneVersion);

            // Create an index writer
            var indexConfig = new IndexWriterConfig(AppLuceneVersion, analyzer);
            using var writer = new IndexWriter(dir, indexConfig);




            var source = new
            {
                Name = "Kermit the Frog",
                FavoritePhrase = "The quick brown fox jumps over the lazy dog"
            };
            var doc = new Document
                {
                    // StringField indexes but doesn't tokenize
                    new StringField("name",
                        source.Name,
                        Field.Store.YES),
                    new TextField("favoritePhrase",
                        source.FavoritePhrase,
                        Field.Store.YES)
                };

            writer.AddDocument(doc);
            writer.Flush(triggerMerge: false, applyAllDeletes: false);



            // Search with a phrase
            var phrase = new MultiPhraseQuery
            {
                new Term("favoritePhrase", "brown"),
                new Term("favoritePhrase", "fox")
            };

            // Re-use the writer to get real-time updates
            using var reader = writer.GetReader(applyAllDeletes: true);
            var searcher = new IndexSearcher(reader);
            var hits = searcher.Search(phrase, 20 /* top 20 */).ScoreDocs;

            // Display the output in a table
            Console.WriteLine($"{"Score",10}" +
                $" {"Name",-15}" +
                $" {"Favorite Phrase",-40}");
            foreach (var hit in hits)
            {
                var foundDoc = searcher.Doc(hit.Doc);
                Console.WriteLine($"{hit.Score:f8}" +
                    $" {foundDoc.Get("name"),-15}" +
                    $" {foundDoc.Get("favoritePhrase"),-40}");
            }

            Console.ReadKey();






        }


        private string dsd()
        {
            //索引保存位置
            var basePath = AppDomain.CurrentDomain.BaseDirectory;


            var indexPath = Path.Combine(basePath, "Index");
            if (!Directory.Exists(indexPath))
                Directory.CreateDirectory(indexPath);


            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            if (IndexWriter.IsLocked(directory))
            {
                //  如果索引目录被锁定（比如索引过程中程序异常退出），则首先解锁
                //  Lucene.Net在写索引库之前会自动加锁，在close的时候会自动解锁
                IndexWriter.Unlock(directory);
            }
            //Lucene的index模块主要负责索引的创建
            //  创建向索引库写操作对象  IndexWriter(索引目录,指定使用盘古分词进行切词,最大写入长度限制)
            //  补充:使用IndexWriter打开directory时会自动对索引库文件上锁
            //IndexWriter构造函数中第一个参数指定索引文件存储位置；
            //第二个参数指定分词Analyzer，Analyzer有多个子类，
            //然而其分词效果并不好，这里使用的是第三方开源分词工具盘古分词；
            //第三个参数表示是否重新创建索引，true表示重新创建（删除之前的索引文件），
            //最后一个参数指定Field的最大数目。
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), true,
                IndexWriter.MaxFieldLength.UNLIMITED);
            var txtPath = Path.Combine(basePath, "Upload\\Articles");
            for (int i = 1; i <= 1000; i++)
            {
                //  一条Document相当于一条记录
                Document document = new Document();
                var title = "天骄战纪_" + i + ".txt";
                var test = Path.Combine(txtPath, title);
                if (System.IO.File.Exists(test))
                {
                    var content = System.IO.File.ReadAllText(test, Encoding.Default);
                    //  每个Document可以有自己的属性（字段），所有字段名都是自定义的，值都是string类型
                    //  Field.Store.YES不仅要对文章进行分词记录，也要保存原文，就不用去数据库里查一次了
                    document.Add(new Field("Title", "天骄战纪_" + i, Field.Store.YES, Field.Index.NOT_ANALYZED));
                    //  需要进行全文检索的字段加 Field.Index. ANALYZED
                    //  Field.Index.ANALYZED:指定文章内容按照分词后结果保存，否则无法实现后续的模糊查询 
                    //  WITH_POSITIONS_OFFSETS:指示不仅保存分割后的词，还保存词之间的距离
                    document.Add(new Field("Content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
                    writer.AddDocument(document);
                }

            }
            writer.Close(); // Close后自动对索引库文件解锁
            directory.Close(); //  不要忘了Close，否则索引结果搜不到
            return "索引创建完毕";
        }
    }
}
